package org.example.spring.poi.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.example.spring.poi.mapper.SysUserMapper;
import org.example.spring.poi.model.entity.SysUser;
import org.example.spring.poi.service.SysUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * @author hzq
 * @since 2022/6/15
 */
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    private final PlatformTransactionManager transactionManager;


    @Override
    public SysUser add(SysUser sysUser) {
        synchronized (this) {
            SysUser byUserName = getByUserName(sysUser.getUsername());
            if (null != byUserName) return byUserName;
            save(sysUser);
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return sysUser;
    }

    @Override
    public SysUser addTransactional(SysUser sysUser) {
        System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());
        synchronized (this) {
            SysUser byUserName = getByUserName(sysUser.getUsername());
            if (null != byUserName) return byUserName;
            TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
            transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            transactionTemplate.setName("org.example.spring.poi.service.impl.SysUserServiceImpl.addTransactional");
            Boolean execute = transactionTemplate.execute(status -> {
                System.out.println("==============");
                System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());
                System.out.println("==============");
                return save(sysUser);
            });
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(TransactionSynchronizationManager.getCurrentTransactionName());
        return sysUser;
    }

    SysUser getByUserName(String username) {
        return getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
    }
}
